package com.asiainfo.framework.config;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.bind.BindResult;
import org.springframework.boot.context.properties.bind.Bindable;
import org.springframework.boot.context.properties.bind.Binder;
import org.springframework.boot.context.properties.source.ConfigurationPropertySources;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MutablePropertySources;

import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * 多数据源配置属性
 */
@ConfigurationProperties(prefix = DataSourceProperties.PREFIX)
public class DataSourceProperties extends LinkedHashMap<String, LinkedHashMap<String, Object>> {

    public static final String PREFIX = "spring.datasource";

    private static DataSourceProperties dataSourceProperties;

    public static class DataSourceConfigurationInitializer implements
            ApplicationContextInitializer<ConfigurableApplicationContext> {

        @Override
        public void initialize(ConfigurableApplicationContext ctx) {
            ConfigurableEnvironment environment = ctx.getEnvironment();
            MutablePropertySources propertySources = environment.getPropertySources();
            Binder binder = new Binder(ConfigurationPropertySources.from(propertySources));
            BindResult<DataSourceProperties> bind = binder.bind(PREFIX, Bindable.ofInstance(new DataSourceProperties()));
            if (bind.isBound()) {
                dataSourceProperties = bind.get();
            }
            if (dataSourceProperties == null) {
                throw new RuntimeException("No DataSource configured");
            }
            frozenProps();
        }

        private void frozenProps() {
            dataSourceProperties.forEach((name, value) -> {
                Collections.unmodifiableMap(value);
            });
            Collections.unmodifiableMap(dataSourceProperties);
        }
    }

    public static DataSourceProperties get() {
        return dataSourceProperties;
    }

    public static boolean isPrimary(Map<String, Object> props) {
        // 单数据源直接设置为Primary Bean
        if (dataSourceProperties.size() == 1) {
            return true;
        }
        Object isPrimary = props.get("primary");
        if (isPrimary == null) {
            return false;
        }
        return Boolean.TRUE.equals(isPrimary);
    }

}
